package com.alibaba.csp.sentinel.demo.spring.web;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.ResourceTypeConstants;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.SentinelWebInterceptor;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.UrlCleaner;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.config.SentinelWebMvcConfig;
import com.alibaba.csp.sentinel.config.SentinelConfig;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.util.StringUtil;

public class CustomerSentinelWebInterceptor extends SentinelWebInterceptor {

	private final SentinelWebMvcConfig config;

	public CustomerSentinelWebInterceptor() {
		this(new SentinelWebMvcConfig());
	}

	public CustomerSentinelWebInterceptor(SentinelWebMvcConfig initconfig) {
		super(initconfig);
		this.config = initconfig;
		 
	}

	@Override
	protected String getResourceName(HttpServletRequest request) {
		// Resolve the Spring Web URL pattern from the request attribute.
		Object resourceNameObject = request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
		if (resourceNameObject == null || !(resourceNameObject instanceof String)) {
			return null;
		}
		String resourceName = (String) resourceNameObject;
		UrlCleaner urlCleaner = config.getUrlCleaner();
		if (urlCleaner != null) {
			resourceName = urlCleaner.clean(resourceName);
		}
		// Add method specification if necessary
		if (StringUtil.isNotEmpty(resourceName) && config.isHttpMethodSpecify()) {
			resourceName = request.getMethod().toUpperCase() + ":" + resourceName;
		}
		
		String[] patterns=getPatterns();
		for (int i=0;i<patterns.length;i=i+2) {
		 Pattern pattern = Pattern.compile(patterns[i]);
			Matcher matcher = pattern.matcher(resourceName);
			if (matcher.matches()) {
				return patterns[i+1];
			}
		}
		return resourceName;
	}
	
	private String[] getPatterns() {
		String patterns=SentinelConfig.getConfig("sentinel.resouce.converge");
		return  patterns.split(",");
		
	}
	

//	private Integer increaseReferece(HttpServletRequest request, String rcKey, int step) {
//		Object obj = request.getAttribute(rcKey);
//
//		if (obj == null) {
//			// initial
//			obj = Integer.valueOf(0);
//		}
//
//		Integer newRc = (Integer) obj + step;
//		request.setAttribute(rcKey, newRc);
//		return newRc;
//	}

//	@Override
//	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
//			throws Exception {
//		try {
//			String resourceName = getResourceName(request);
//			System.out.println("CustomerSentinelWebInterceptor is executing!");
//			if (StringUtil.isEmpty(resourceName)) {
//				return true;
//			}
//
//			if (increaseReferece(request, this.config.getRequestRefName(), 1) != 1) {
//				return true;
//			}
//
//			// Parse the request origin using registered origin parser.
//			String origin = parseOrigin(request);
//			String contextName = getContextName(request);
//			ContextUtil.enter(contextName, origin);
//			Entry entry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_WEB, EntryType.IN);
//			request.setAttribute(config.getRequestAttributeName(), entry);
//			return true;
//		} catch (BlockException e) {
//			try {
//
//				handleBlockException(request, response, e);
//
//			} finally {
//				ContextUtil.exit();
//			}
//			return false;
//		}catch (Exception e) {
//			try {
//				 System.err.println("catch exception:"+e.getClass().getCanonicalName());
//				 throw e;
//
//			} finally {
//				ContextUtil.exit();
//			}
//			 
//		}
//	}
//	
//	@Override
//    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
//                                Object handler, Exception ex) throws Exception {
//        if (increaseReferece(request, this.config.getRequestRefName(), -1) != 0) {
//            return;
//        }
//        
//        Entry entry = getEntryInRequest(request, config.getRequestAttributeName());
//        if (entry == null) {
//            // should not happen
//            RecordLog.warn("[{}] No entry found in request, key: {}",
//                    getClass().getSimpleName(), config.getRequestAttributeName());
//            return;
//        }
//        
//        if (ex !=null) {
//        	System.err.println("ex="+ex.getClass().getCanonicalName());
//        }
//        traceExceptionAndExit(entry, ex);
//        removeEntryInRequest(request);
//        ContextUtil.exit();
//    }
 
}
